package com.ds.home.proxy;

import com.alibaba.fastjson.annotation.JSONField;
import com.ds.command.CommandFactory;
import com.ds.common.JDSException;
import com.ds.common.util.StringUtility;
import com.ds.home.EIPlace;
import com.ds.home.client.CommandClient;
import com.ds.home.engine.AppEngine;
import com.ds.iot.Area;
import com.ds.iot.HomeException;
import com.ds.iot.Place;
import com.ds.iot.ZNode;
import com.ds.iot.enums.DeviceStatus;

import java.util.*;

public class PlaceProxy implements Place {
    @JSONField(serialize = false)

    private EIPlace dbPlace;
    @JSONField(serialize = false)
    private String systemCode;

    @JSONField(serialize = false)

    private List<ZNode> startSensorList;
    @JSONField(serialize = false)

    private List<ZNode> indexSensorList;


    public PlaceProxy(EIPlace dbPlace, String systemCode) {
        this.dbPlace = dbPlace;
        this.systemCode = systemCode;


    }

    public Set<String> getChildIds() {
        Set<String> ids = new LinkedHashSet<>();
        List<Place> places = AppEngine.getEngine(systemCode).getChildPlaces(this.getPlaceid());
        for (Place place : places) {
            ids.add(place.getPlaceid());
        }

        return ids;
    }

    @JSONField(serialize = false)
    public List<Place> getChilders() {
        List<Place> places = AppEngine.getEngine(systemCode).getChildPlaces(this.getPlaceid());
        return places;
    }

    public List<Area> getAreas() {
        List<Area> areas = new ArrayList<Area>();
        try {
            areas = AppEngine.getEngine(systemCode).getAllAreaByPlaceId(this.getPlaceid());
        } catch (HomeException e) {

        }
        return areas;
    }

    public String getName() {
        return dbPlace.getName();
    }

    public String getPlaceid() {
        return dbPlace.getPlaceid();
    }

    public String getUserid() {
        return dbPlace.getUserid();
    }

    @JSONField(serialize = false)
    public List<ZNode> getZnodes() {
        Set<ZNode> sensorList = new LinkedHashSet<>();
        List<Area> areas = this.getAreas();
        for (Area area : areas) {
            sensorList.addAll(area.getSensors());
        }
        return new ArrayList<>(sensorList);
    }

    public void setMemo(String memo) {
        dbPlace.setMemo(memo);
    }

    public void setName(String name) {
        dbPlace.setName(name);
    }

    public void setPlaceid(String placeid) {
        dbPlace.setPlaceid(placeid);
    }

    public void setStart(String start) {
        dbPlace.setStart(start);
    }

    public void setUserid(String userid) {
        dbPlace.setUserid(userid);
    }

    public String getMemo() {
        return dbPlace.getMemo();
    }

    public String getStart() {
        return dbPlace.getStart();
    }

    @JSONField(serialize = false)
    public List<ZNode> getIndexSensorList() {
        if (this.indexSensorList == null) {
            indexSensorList = new ArrayList<ZNode>();
            String startStr = dbPlace.getMemo();
            String[] startArr = StringUtility.split(startStr, ",");

            List<String> startList = new ArrayList<String>();
            for (String znodeId : startArr) {
                ZNode node = null;
                try {
                    node = AppEngine.getEngine(systemCode).getZNodeById(znodeId);
                    if (this.getZnodes().contains(node)) {
                        indexSensorList.add(node);
                    } else {
                        startList.add(znodeId);
                    }
                } catch (HomeException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            }

        }

        return indexSensorList;
    }

    @JSONField(serialize = false)
    public List<ZNode> getStartSensorList() {
        if (this.startSensorList == null) {
            startSensorList = new ArrayList<ZNode>();
            String startStr = dbPlace.getStart();
            String[] startArr = StringUtility.split(startStr, ",");
            List<String> startList = new ArrayList<String>();
            for (String znodeId : startArr) {
                ZNode node = null;
                try {
                    node = AppEngine.getEngine(systemCode).getZNodeById(znodeId);
                } catch (HomeException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                if (this.getZnodes().contains(node)) {
                    startSensorList.add(node);
                } else {
                    startList.add(znodeId);
                }

            }

        }

        return startSensorList;
    }

    @JSONField(serialize = false)
    public List<ZNode> getGateways() {
        List<ZNode> sensorList = new ArrayList<ZNode>();
        Set<String> gatewayIds = this.getGatewayIds();

        for (String znodeId : gatewayIds) {
            ZNode znode = null;
            try {
                znode = AppEngine.getEngine(systemCode).getZNodeById(znodeId);
            } catch (HomeException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            if (znode != null) {
                znode.setStatus(DeviceStatus.OFFLINE);
                CommandClient commandClient = null;
                try {
                    commandClient = CommandFactory.getInstance().getCommandClientByieee(znode.getEndPoint().getDevice().getSerialno());
                } catch (JDSException e) {
                    e.printStackTrace();
                }
                if (commandClient == null) {
                    znode.setStatus(DeviceStatus.ONLINE);
                }

                sensorList.add(znode);
            }

        }
        return sensorList;
    }

    @JSONField(serialize = false)

    public List<ZNode> getSensors() {

        return this.getZnodes();
    }


    public String getOrgid() {
        return dbPlace.getOrgid();
    }


    public void setOrgid(String orgid) {
        dbPlace.setOrgid(orgid);
        ;
    }


    public Set<String> getAreaIds() {
        return dbPlace.getAreaIds();
    }

    @JSONField(serialize = false)
    public List<String> getSensorIds() {
        List<String> sensorIds = new ArrayList<String>();
        List<Area> areas = this.getAreas();
        for (Area area : areas) {
            sensorIds.addAll(area.getSensorIds());
        }
        return sensorIds;
    }


    public Set<String> getGatewayIds() {
        Set<String> gatewayIds = new LinkedHashSet<String>();


        try {
            gatewayIds = AppEngine.getEngine(systemCode).getAllGatewayIdsByPlaceId(this.getPlaceid());
        } catch (HomeException e) {
            e.printStackTrace();
        }

        return gatewayIds;
    }


    public Set<String> getIndexSensorIdList() {
        Set<String> indexSensorIdList = new LinkedHashSet<>();

        String startStr = dbPlace.getMemo();
        if (startStr != null) {
            String[] startArr = StringUtility.split(startStr, ",");
            indexSensorIdList = new LinkedHashSet<>(Arrays.asList(startArr));
        }

        return indexSensorIdList;
    }


    public String getParentId() {
        return dbPlace.getParentId();
    }


    public void setParentId(String parentid) {
        dbPlace.setParentId(parentid);
    }

    @Override
    public boolean equals(Object obj) {
        if (obj != null && obj instanceof Place) {
            Place place = (Place) obj;
            return place.getPlaceid().equals(this.getPlaceid());
        }
        return super.equals(obj);
    }

    @JSONField(serialize = false)
    public Place getParent() {
        try {
            return AppEngine.getEngine(systemCode).getPlaceById(dbPlace.getParentId());
        } catch (HomeException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }
}
